package main

import (
	"encoding/json"
	"fmt"
	"html/template"
	"io/ioutil"
	"log"
	"math/rand"
	"net/http"
	"os"
	"path/filepath"
	"time"
)

const dataDir = "./data"

type DataEntry struct {
	Data       string    `json:"data"`
	CreateTime time.Time `json:"createTime"`
	DeleteTime time.Time `json:"deleteTime"`
}

var tmpl = template.Must(template.ParseFiles("index.html"))

func startCleanupTask() {
	ticker := time.NewTicker(1 * time.Hour)
	go func() {
		for {
			select {
			case <-ticker.C:
				err := cleanupExpiredFiles()
				if err != nil {
					log.Printf("清理任务失败: %v", err)
				}
			}
		}
	}()
}

func cleanupExpiredFiles() error {
	files, err := ioutil.ReadDir(dataDir)
	if err != nil {
		return err
	}

	now := time.Now()

	for _, file := range files {
		if filepath.Ext(file.Name()) != ".json" {
			continue
		}

		filePath := filepath.Join(dataDir, file.Name())
		data, err := ioutil.ReadFile(filePath)
		if err != nil {
			log.Printf("读取文件失败: %v", err)
			continue
		}

		var entry DataEntry
		if err := json.Unmarshal(data, &entry); err != nil {
			log.Printf("解析文件失败: %v", err)
			continue
		}

		if now.After(entry.DeleteTime) {
			err := os.Remove(filePath)
			if err != nil {
				log.Printf("删除文件失败: %v", err)
			} else {
				log.Printf("已删除过期文件: %s", filePath)
			}
		}
	}

	return nil
}

func main() {
	os.MkdirAll(dataDir, 0755)
	startCleanupTask() // 添加这行
	http.HandleFunc("/", handleRequest)
	http.ListenAndServe(":8080", nil)
}

func handleRequest(w http.ResponseWriter, r *http.Request) {
	path := r.URL.Path
	if path == "/" {
		switch r.Method {
		case http.MethodGet:
			handleRootGet(w, r)
		case http.MethodPost:
			handleRootPost(w, r)
		default:
			http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		}
		return
	}
	id := r.URL.Path[1:]
	if id == "" {
		http.NotFound(w, r)
		return
	}

	switch r.Method {
	case http.MethodGet:
		handleGet(id, w, r)
	case http.MethodPost:
		handlePost(id, w, r)
	default:
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
	}
}
func handleRootGet(w http.ResponseWriter, r *http.Request) {
	tmpl.Execute(w, struct {
		Data       string
		DeleteTime string
	}{
		Data:       "",
		DeleteTime: "", // 明确传递空值
	})
}

func handleRootPost(w http.ResponseWriter, r *http.Request) {
	var req struct {
		Data    string `json:"data"`
		Minutes int    `json:"minutes"`
	}
	json.NewDecoder(r.Body).Decode(&req)

	minutes := req.Minutes
	if minutes <= 0 {
		minutes = 60
	}

	now := time.Now()
	entry := DataEntry{
		Data:       req.Data,
		CreateTime: now,
		DeleteTime: now.Add(time.Duration(minutes) * time.Minute),
	}

	id := generateUniqueID()
	saveData(id, entry)

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(map[string]string{"redirect": "/" + id})
}
func generateUniqueID() string {
	for {
		id := rand.Intn(900000) + 100000 // 生成6位随机数
		filePath := filepath.Join(dataDir, fmt.Sprintf("%d.json", id))
		if _, err := os.Stat(filePath); os.IsNotExist(err) {
			return fmt.Sprintf("%d", id)
		}
	}
}
func handleGet(id string, w http.ResponseWriter, r *http.Request) {
	if r.URL.Query().Get("json") == "true" {
		handleJSON(id, w)
		return
	}
	handleUI(id, w)
}

func handleJSON(id string, w http.ResponseWriter) {
	entry, exists := loadData(id)
	if !exists || entry == nil {
		http.NotFound(w, nil)
		return
	}

	// 直接返回纯文本内容
	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
	w.Write([]byte(entry.Data))
}
func handleUI(id string, w http.ResponseWriter) {
	entry, _ := loadData(id)
	// 格式化时间（后端处理）
	formattedDeleteTime := ""
	if !entry.DeleteTime.IsZero() {
		formattedDeleteTime = entry.DeleteTime.Format(time.RFC3339)
	}

	tmpl.Execute(w, struct {
		Data       string
		DeleteTime string // 直接传递格式化后的字符串
	}{
		Data:       entry.Data,
		DeleteTime: formattedDeleteTime,
	})

}

type saveRequest struct {
	Data    string `json:"data"`
	Minutes int    `json:"minutes"` // 新增字段
}

func handlePost(id string, w http.ResponseWriter, r *http.Request) {
	var req saveRequest
	json.NewDecoder(r.Body).Decode(&req)

	minutes := req.Minutes
	if minutes <= 0 {
		minutes = 60 // 默认值保持兼容
	}

	entry := DataEntry{
		Data:       req.Data,
		CreateTime: time.Now(),
		DeleteTime: time.Now().Add(time.Duration(minutes) * time.Minute),
	}

	saveData(id, entry)
	w.WriteHeader(http.StatusOK)

}

func loadData(id string) (*DataEntry, bool) {
	filePath := filepath.Join(dataDir, id+".json")
	data, err := os.ReadFile(filePath)
	if err != nil {
		return &DataEntry{}, false
	}

	var entry DataEntry
	json.Unmarshal(data, &entry)

	if time.Now().After(entry.DeleteTime) {
		os.Remove(filePath)
		return &DataEntry{}, false
	}

	return &entry, true
}

func saveData(id string, entry DataEntry) {
	filePath := filepath.Join(dataDir, id+".json")
	data, _ := json.Marshal(entry)
	os.WriteFile(filePath, data, 0644)
}
